package j.framework.qmd.jdbc;

import j.framework.base.service.impl.ApplicationServiceImpl;
import j.framework.core.LoginUser;
import j.framework.core.WebRequestConfiguration;
import j.framework.qmd.core.*;
import j.framework.qmd.supported.EntityUtils;
import j.data.ActionResult;
import j.data.PagedData;
import j.util.*;
import j.util.jdbc.*;
import j.util.jdbc.JdbcUtils;
import j.util.pkgenerator.PG;

import java.sql.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 自定义查询模块所依赖的业务层
 * User: jason
 * Date: 14-7-28 上午10:02
 */
public class QueryMetadataServiceImpl implements QueryMetadataService {

    private JdbcTemplate jdbcTemplate = SpringBeans.getBean(JdbcTemplate.class);

    @Override
    public PagedData<List<QueryMetadata>> getQueryList(LoginUser user, String fid, int page, int rows) {
        if(StringUtils.isNullOrEmpty(fid)){
            return PagedData.NULL;
        }
        String sql = "select * from sys_query_metadata where function_id=? order by added_time desc";
        return jdbcTemplate.queryForPaging(sql,queryMetadataRowMapper,page,rows,fid);
    }

    @Override
    public QueryMetadata getQueryMetadata(String queryId) {
        return jdbcTemplate.queryForDomain("select * from sys_query_metadata where query_md_id=?", queryMetadataRowMapper, queryId);
    }

    private static RowMapper<QueryMetadata> queryMetadataRowMapper = new RowMapper<QueryMetadata>() {
        @Override
        public QueryMetadata mapRow(ResultSet rs, int rowNum) throws SQLException {
            QueryMetadata qmd = new QueryMetadata();
            qmd.setQueryId(rs.getString("query_md_id"));
            qmd.setFunctionId(rs.getString("function_id"));
            qmd.setQueryKey(rs.getString("query_key"));
            qmd.setName(rs.getString("name"));
            qmd.setQuerySql(rs.getString("query_sql"));

            qmd.setNamedSql(rs.getBoolean("is_named_sql"));
            qmd.setStoreProcedure(rs.getBoolean("is_store_procedure"));

            qmd.setPagingSupported(rs.getBoolean("paging_supported"));
            qmd.setFooterSupported(rs.getBoolean("footer_supported"));
            qmd.setFooterOptions(rs.getString("footer_options"));
            qmd.setDataHandlerClassName(rs.getString("data_handler_class_name"));
            qmd.setBuildWhereMethodName(rs.getString("build_where_method_name"));
            qmd.setOperatorSupported(rs.getBoolean("operator_supported"));
            qmd.setAddedUserId(rs.getString("added_user_id"));
            qmd.setAddedTime(JdbcUtils.getDateFromResultSet(rs, "added_time"));

            qmd.setColumnMovingSupported(rs.getBoolean("column_moving_supported"));
            qmd.setMultiColumnSortedSupported(rs.getBoolean("multi_column_sorted_supported"));//多表头支持
            qmd.setMultiSelectSupported(rs.getBoolean("multi_select_supported"));   //多行选择支持
            qmd.setRowClick(rs.getString("row_click"));
            qmd.setRowStyler(rs.getString("row_styler"));
            qmd.setShowByTree(rs.getBoolean("is_tree"));
            qmd.setShowRowNumbers(rs.getBoolean("is_show_row_numbers"));
            qmd.setDefaultPageSize(JdbcUtils.getInteger(rs, "default_page_size"));
            qmd.setDefaultPageList(rs.getString("default_page_list"));
            qmd.setFrozenLeftColumns(JdbcUtils.getInteger(rs,"frozen_left_columns"));
            qmd.setFrozenRightColumns(JdbcUtils.getInteger(rs,"frozen_right_columns"));
            qmd.setFrozenTopRows(JdbcUtils.getInteger(rs,"frozen_top_rows"));
            return qmd;
        }
    };

    /**
     * 获取元数据时调用此方法
     * @param queryId
     * @return
     */
    @Override
    public QueryMetadata getFullQueryMetadata(String queryId) {
        QueryJdbcTemplate qjt = new QueryJdbcTemplate(jdbcTemplate.getDataSource());
        try{
            if(queryId.length()!=20){
                queryId = (String)qjt.queryForObject("select query_md_id from sys_query_metadata where query_key=?",queryId);
            }
            final QueryMetadata qmd = qjt.queryForDomain("select * from sys_query_metadata where query_md_id=?",
                    queryMetadataRowMapper, queryId);
            final List<DataColumn> pks = New.list(2);
            final List<QuerySort> qs = New.list(2);
            if(qmd != null){
                //获取此查询定义的所有字段定义
                qjt.queryForList("select * from sys_query_field_metadata where query_md_id=? order by display_order",
                        new ResultSetHandler() {
                            QueryFieldMetadata qfmd;
                            @Override
                            public void doResultSet(ResultSet rs) throws SQLException {
                                qfmd = getQueryFieldMetadataFromResultSet(rs);
                                if(qfmd.isPrimaryKey()){
                                    //当前字段是主键
                                    pks.add(new DataColumn(
                                            qfmd.isUsedFieldNameAsKey(),
                                            qfmd.getFieldId(),
                                            qfmd.getTableAliasName(),qfmd.getFieldName()));
                                }
                                if(qfmd.isDefaultSort()){
                                    QuerySort sort = new QuerySort();
                                    sort.setUsedFieldNameAsKey(qfmd.isUsedFieldNameAsKey());
                                    sort.setQueryFieldMetadataId(qfmd.getFieldId());
                                    sort.setTableAliasName(qfmd.getTableAliasName());
                                    sort.setColumnName(qfmd.getFieldName());
                                    sort.setOrderBy(qfmd.getDefaultSortOrder());
                                    if(StringUtils.isNullOrEmpty(sort.getOrderBy())){
                                        sort.setOrderBy("ASC");
                                    }
                                    qs.add(sort);
                                }
                                if(qfmd.isAsTreeField()){
                                    qmd.setTreeField(new DataColumn(
                                            qfmd.isUsedFieldNameAsKey(),
                                            qfmd.getFieldId(),qfmd.getTableAliasName(),
                                            qfmd.getFieldName()
                                    ));
                                }
                                qmd.putFieldMetadata(qfmd);

                            }
                        },queryId);
            }else{
                throw new RuntimeException(queryId+"查询ID为"+queryId+"没有定义，请与系统管理员联系！");
            }
            if(pks.size()>0){
                qmd.setPrimaryKeys(pks);
            }
            if(qs.size()>0){
                qmd.setDefaultQuerySort(qs);
            }
            //获取此查询的footer定义
            List<QueryFieldFooter> footers = jdbcTemplate.queryForList("select * from sys_query_field_footers where query_field_id in (select query_field_id from sys_query_field_metadata where query_md_id=?)",
                    new RowMapper<QueryFieldFooter>() {
                        @Override
                        public QueryFieldFooter mapRow(ResultSet rs, int rowNum) throws SQLException {
                            QueryFieldFooter footer = new QueryFieldFooter();
                            footer.setFieldId(rs.getString("query_field_id"));
                            footer.setCalcType(rs.getString("calc_type"));
                            footer.setFormatOptions(rs.getString("format_options"));
                            footer.setRowNumber(rs.getInt("display_order"));
                            return footer;
                        }
                    }, queryId);
            if(footers != null && footers.size() > 0){
                qmd.setFooters(footers);
            }
            //获取此查询的操作定义
            Map<String,Object> args = New.map();
            args.put("queryId",qmd.getQueryId());
            List<QueryOperation> operations = jdbcTemplate.queryForList(QueryOperation.class,args,null);
            qmd.setOperations(operations);
            return qmd;
        }finally {
            qjt.close();
        }
    }

    @Override
    public void saveQueryMetadata(LoginUser user, QueryMetadata qmd, ActionResult ar) {
        ar.hasLength("function_id",qmd.getFunctionId(),"请选择此查询属于哪个模块!");
        ar.hasLength("name",qmd.getName(),"请输入查询名称!");
        ar.hasLength("sql",qmd.getQuerySql(),"请输入查询SQL语句!");
        if(ar.isOk()){
            TransactionalJdbcTemplate tjt = new TransactionalJdbcTemplate(jdbcTemplate.getDataSource(),true);
            try{
                boolean needAddFields = true;
                Map<String,Object> map = New.map();
                map.put("function_id",qmd.getFunctionId());
                map.put("query_key",qmd.getQueryKey());
                map.put("name",qmd.getName());
                map.put("paging_supported",qmd.isPagingSupported());
                map.put("default_page_size",qmd.getDefaultPageSize());
                map.put("default_page_list",qmd.getDefaultPageList());
                map.put("footer_supported",qmd.isFooterSupported());
                map.put("footer_options",qmd.getFooterOptions());
                map.put("data_handler_class_name",qmd.getDataHandlerClassName());
                map.put("build_where_method_name",qmd.getBuildWhereMethodName());
                map.put("operator_supported",qmd.isOperatorSupported());
                map.put("column_moving_supported",qmd.isColumnMovingSupported());
                map.put("multi_column_sorted_supported",qmd.isMultiColumnSortedSupported());
                map.put("row_click",qmd.getRowClick());
                map.put("row_styler",qmd.getRowStyler());
                map.put("multi_select_supported",qmd.isMultiSelectSupported());
                map.put("is_tree",qmd.isShowByTree());
                map.put("is_show_row_numbers",qmd.isShowRowNumbers());
                map.put("frozen_left_columns",qmd.getFrozenLeftColumns());
                map.put("frozen_right_columns",qmd.getFrozenRightColumns());
                map.put("frozen_top_rows",qmd.getFrozenTopRows());

                map.put("is_named_sql",qmd.isNamedSql());
                map.put("is_store_procedure",qmd.isStoreProcedure());
                if(StringUtils.isNotEmpty(qmd.getQueryId())){
                    //这是修改
                    //先对比一下sql语句是否有变化，若没有变化，则不再修改sql语句
                    String dbSql = (String)tjt.queryForObject("select query_sql from sys_query_metadata where query_md_id=?",qmd.getQueryId());
                    if(StringUtils.isNotEmpty(dbSql) && dbSql.equals(qmd.getQuerySql())){
                        //没有变化
                        tjt.executeUpdate("sys_query_metadata",map,"query_md_id=?",qmd.getQueryId());
                        needAddFields = false;
                    }else{
                        map.put("query_sql",qmd.getQuerySql());
                        tjt.executeUpdate("sys_query_metadata",map,"query_md_id=?",qmd.getQueryId());
                        //删除所有先前生成的定义，需要再重新定义
                        //tjt.execute("delete from sys_query_field_metadata where query_md_id=?",qmd.getQueryId());
                    }
                }else{
                    //这是增加
                    qmd.setQueryId(PG.getNext("s11"));
                    qmd.setAddedUserId(user.getUserId());
                    qmd.setAddedTime(new Date());
                    map.put("query_sql",qmd.getQuerySql());
                    map.put("query_md_id", qmd.getQueryId());
                    map.put("added_user_id",qmd.getAddedUserId());
                    map.put("added_time",qmd.getAddedTime());
                    tjt.executeInsert("sys_query_metadata",map);
                }
                if(needAddFields){
                    //需要根据sql语句解析出所有字段，并增加到子表中
                    List<Object[]> argsList = New.list();
                    String batchInsertSql = "insert into sys_query_field_metadata(query_field_id,query_md_id,table_alias_name,field_name,display_name,display_name_tag,width,data_type,is_pk,sort_supported,column_data_align,column_header_align,footer_calc_supported,display_order,client_formatter,formatter_method_name,as_default_sort)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
                    //todo 待找到解决getTableName不为空的解决方案

                    Connection conn  = tjt.getConnection();
                    /*Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                    String connectionUrl = "jdbc:sqlserver://116.255.255.131:30300;databaseName=OrendaPortal";
                    Properties info = new java.util.Properties();
                    info.put ("user","OrendaPortalManager");
                    info.put ("password","dc3c6bfc820f816f998ab1ed45633");
                    info.put ("ResultSetMetaDataOptions",1);
                    conn = DriverManager.getConnection(connectionUrl,info);*/

                    /*Class.forName("net.sourceforge.jtds.jdbc.Driver");
                    String connectionUrl = "jdbc:jtds:sqlserver://116.255.255.131:30300;DatabaseName=OrendaPortal;ResultSetMetaDataOptions=1";
                    Properties info = new java.util.Properties();
                    info.put ("user","OrendaPortalManager");
                    info.put ("password","dc3c6bfc820f816f998ab1ed45633");
                    conn = DriverManager.getConnection(connectionUrl,info);*/

                    String sql = qmd.getQuerySql();
                    if(sql.contains("@@")){
                        sql = sql.replaceFirst("@@","");
                    }
                    //去除sql语句的where部分
                    int whereIndex = sql.toLowerCase().indexOf("where");
                    if(whereIndex>-1){
                        sql = sql.substring(0,whereIndex);
                    }
                    ResultSetMetaData rsmd;
                    if(qmd.isStoreProcedure()){
                        CallableStatement callStmt = conn.prepareCall(sql);
                        rsmd = callStmt.getMetaData();
                    }else{
                        PreparedStatement stmt = conn.prepareStatement(sql);
                        rsmd = stmt.getMetaData();
                    }

                    /*if(null!=listArgs&&listArgs.size()>0){
                        JdbcUtils.setStatementArguments(stmt,listArgs.toArray());
                    }*/

                    Object[] args;
                    int index ;
                    DataType dt;
                    int cnt;
                    int width;
                    for(int i=1;i<=rsmd.getColumnCount();i++){
                        //先判断一下表中是否已有定义，若已有，则不做增加操作
                        cnt = tjt.queryForInt("select count(*) from sys_query_field_metadata where query_md_id=? and field_name=?",
                                qmd.getQueryId(),rsmd.getColumnName(i));
                        if(cnt>0){
                            //已经有定义了，不做增加
                            continue;
                        }
                        index = 0;
                        args = new Object[17];
                        args[index++] = PG.getNext("s12");
                        args[index++] = qmd.getQueryId();
                        args[index++] = rsmd.getTableName(i);
                        args[index++] =  rsmd.getColumnName(i);
                        args[index++] = args[3];//显示名称
                        args[index++] = null;//display_tag 多标题用此字段

                        dt = EntityUtils.fromDbDataTypeToJavaType(rsmd, i);
                        width = 0;
                        if(dt.equals(DataType.DATE)){
                            width = 100;
                        }else if(dt.equals(DataType.DATETIME)){
                            width = 130;
                        }else if(dt.equals(DataType.INTEGER)
                                || dt.equals(DataType.LONG)
                                || dt.equals(DataType.FLOAT)
                                || dt.equals(DataType.DOUBLE)){
                            width = 80;
                        }else if(dt.equals(DataType.BOOLEAN)){
                            width = 60;
                        }
                        args[index++] = width;//宽度

                        args[index++] = dt.toString();//data_type
                        args[index++] = false;//默认都不是主键
                        args[index++] = true;//支持排序
                        if(dt.equals(DataType.INTEGER)
                                || dt.equals(DataType.LONG)
                                || dt.equals(DataType.FLOAT)
                                || dt.equals(DataType.DOUBLE)){
                            args[index++] = DataAlign.RIGHT.toString();
                        }else{
                            args[index++] = DataAlign.LEFT.toString();
                        }
                        args[index++] = DataAlign.CENTER.toString();
                        args[index++] = false;//footer_calc_supported
                        args[index++] = i*10;  //显示顺序
                        args[index++]= null;//client_formatter
                        args[index++]= null;//formatter_method_name
                        args[index]= false;//as_default_sort
                        argsList.add(args);
                    }
                    if(argsList.size()>0){
                        tjt.executeBatch(batchInsertSql,argsList);
                    }
                }
                tjt.commit();
            }catch (Exception e){
                tjt.rollback();
                e.printStackTrace();
                ar.add("保存时出错，请检查sql语句是否正确！异常信息："+e.getMessage());
            }finally {
                tjt.close();
            }
        }
    }

    @Override
    public void deleteQueryMetadata(LoginUser user, String queryId, ActionResult ar) {
        TransactionalJdbcTemplate tjt = new TransactionalJdbcTemplate(jdbcTemplate.getDataSource(),true);
        try{
            //删除所有footer
            tjt.execute("delete from sys_query_field_footers where query_field_id in (select query_field_id from sys_query_field_metadata where query_md_id=?)",
                    queryId);
            //删除所有字段
            tjt.execute("delete from sys_query_field_metadata where query_md_id=?",queryId);
            //删除查询
            tjt.execute("delete from sys_query_metadata where query_md_id=?",queryId);
            tjt.commit();
        }catch (Exception e){
            tjt.rollback();
            e.printStackTrace();
        }finally {
            tjt.close();
        }
    }

    @Override
    public List<QueryFieldMetadata> getQueryFieldMetadataList(String queryId) {
        return jdbcTemplate.queryForList("select * from sys_query_field_metadata where query_md_id=? order by display_order",
                new RowMapper<QueryFieldMetadata>() {
                    @Override
                    public QueryFieldMetadata mapRow(ResultSet rs, int rowNum) throws SQLException {
                        return getQueryFieldMetadataFromResultSet(rs);
                    }
                },queryId);
    }

    @Override
    public void doSaveQueryFieldMetadata(LoginUser user, String queryId, String treeFieldId, String treeParentFieldId, List<QueryFieldMetadata> list, ActionResult ar) {
        String sql = "update sys_query_field_metadata set table_alias_name=?,display_name=?,display_name_tag=?,width=?,data_type=?,is_pk=?,suppressible=?,sort_supported=?,as_default_sort=?,default_sort_order=?,display_order=?,column_data_align=?,column_header_align=?,client_formatter=?,formatter_method_name=?,format_type=?,dictionary_id=?,format_options=?,used_field_name_as_key=? where query_field_id=?";
        List<Object[]> argsList = New.list();
        int index ;
        for(QueryFieldMetadata md : list){
            index = 0;
            Object[] args = new Object[20];
            args[index++] = md.getTableAliasName();
            args[index++] = md.getDisplayName();
            args[index++] = md.getDisplayNameTag();
            args[index++] = md.getWidth();
            args[index++] = md.getDataType().name();
            args[index++] = md.isPrimaryKey();
            args[index++] = md.isSuppressible();
            args[index++] = md.isSortSupported();
            args[index++] = md.isDefaultSort();
            args[index++] = md.getDefaultSortOrder();
            args[index++] = md.getDisplayOrder();
            args[index++] = md.getColumnDataAlign().name();
            args[index++] = md.getColumnHeaderAlign().name();
            args[index++] = md.getClientFormatter();
            args[index++] = md.getFormatterMethodName();
            args[index++] = md.getFormatType().name();
            args[index++] = md.getDictionaryId();
            args[index++] = md.getFormatOptions();
            args[index++] = md.isUsedFieldNameAsKey();
            args[index] = md.getFieldId();
            argsList.add(args);
        }
        TransactionalJdbcTemplate tjt = new TransactionalJdbcTemplate(jdbcTemplate.getDataSource(),true);
        try{
            if(StringUtils.isNotEmpty(treeFieldId)){
                //这是树形查询
                //先清除原来的树形字段
                tjt.execute("update sys_query_field_metadata set as_tree_field=0 where query_md_id=? and as_tree_field=1",queryId);
                tjt.execute("update sys_query_field_metadata set as_tree_field=1 where query_field_id=?",treeFieldId);
                //再清除原来的树形父级字段
                tjt.execute("update sys_query_field_metadata set as_tree_parent_field=0 where query_md_id=? and as_tree_parent_field=1",queryId);
                tjt.execute("update sys_query_field_metadata set as_tree_parent_field=1 where query_field_id=?",treeParentFieldId);
            }
            tjt.executeBatch(sql,argsList);
            tjt.commit();
        }catch (Exception e){
            tjt.rollback();
            ar.add("保存数据时失败，异常："+e.getMessage());
        }finally {
            tjt.close();
        }
    }

    @Override
    public List<WebRequestConfiguration> getWebRequests(String functionId) {
        List<Object> args = New.list();
        String sql = "select *,(select moduleName from bas_Module where moduleID=r.function_id) as function_name,(select authName from bas_ModuleAuth where moduleAuthID=r.action_id) as action_name from sys_web_request r";
        if(StringUtils.isNotEmpty(functionId)){
            sql += " where function_id=?";
            args.add(functionId);
        }
        return jdbcTemplate.queryForList(sql,
                ApplicationServiceImpl.webRequestRowMapper,args.toArray());
    }

    @Override
    public void saveWebRequestConfiguration(LoginUser user, WebRequestConfiguration wrc, ActionResult ar) {
        //先验证
        if(StringUtils.isNotEmpty(wrc.getFunctionId())){
            wrc.setFunctionId(DES.decrypt(wrc.getFunctionId()));
        }
        if(wrc.isUsedGeneralService() && wrc.getResponseType().equals(WebRequestConfiguration.RESPONSE_TYPE_FORWARD)){
            ar.hasLength("url",wrc.getUrl(),"响应处理方式为[forward]时，URL是必须的！");
            ar.hasLength("gkey",wrc.getEntityPkGenerateKey(),"请输入主键生成器KEY!");
            ar.hasLength("entityClassName",wrc.getEntityClassName(),"请输入实体类类名，（包名+类名）");
        }else if(wrc.getResponseType().equals(WebRequestConfiguration.RESPONSE_TYPE_ONLY_FORWARD)
                || wrc.getResponseType().equals(WebRequestConfiguration.RESPONSE_TYPE_REDIRECT)) {
            ar.hasLength("url",wrc.getUrl(),"响应处理方式为[only_forward]时，URL是必须的！");
        }else{
            ar.hasLength("beanClassName",wrc.getBeanClassName(),"请输入调用业务BEAN的类名，（包名+类名）");
            ar.hasLength("beanClassMethodName",wrc.getBeanClassMethodName(),"请输入调用业务BEAN的类方法名!");
        }
        if(ar.isOk()){
            Map<String,Object> mapData = New.map();
            mapData.put("name",wrc.getRequestName());
            mapData.put("function_id",wrc.getFunctionId());
            mapData.put("action_id",wrc.getActionId());
            mapData.put("check_function_privilege",wrc.isCheckFunctionPrivilege());
            mapData.put("check_action_privilege",StringUtils.isNotEmpty(wrc.getActionId()));
            mapData.put("request_type",wrc.getRequestType());
            mapData.put("response_type",wrc.getResponseType());
            mapData.put("log_supported",wrc.isLogSupported());
            mapData.put("general_action",wrc.getGeneralAction());
            mapData.put("url",wrc.getUrl());
            mapData.put("used_general_service",wrc.isUsedGeneralService());
            if(wrc.isUsedGeneralService() && wrc.getResponseType().equals(WebRequestConfiguration.RESPONSE_TYPE_FORWARD)){
                mapData.put("entity_class_name",wrc.getEntityClassName());
                mapData.put("pk_tbl_key",wrc.getEntityPkGenerateKey());
                mapData.put("entity_trigger",wrc.getEntityTrigger());
            }
            mapData.put("bean_class_name",wrc.getBeanClassName());
            mapData.put("bean_class_method_name",wrc.getBeanClassMethodName());
            if(StringUtils.isNullOrEmpty(wrc.getRequestId())){
                //这是增加
                wrc.setRequestId(PG.getNext("REQ"));
                wrc.setAddedUserId(user.getUserId());
                wrc.setAddedTime(new Date());
                mapData.put("request_id",wrc.getRequestId());
                mapData.put("added_user_id",wrc.getAddedUserId());
                mapData.put("added_time",wrc.getAddedTime());
                jdbcTemplate.executeInsert("sys_web_request",mapData);
            }else{
                //这是修改
                jdbcTemplate.executeUpdate("sys_web_request",mapData,"request_id=?",wrc.getRequestId());
            }
        }
    }

    @Override
    public void deleteWebRequestConfiguration(LoginUser user, String requestId, ActionResult ar) {
        jdbcTemplate.execute("delete from sys_web_request where request_id=?",requestId);
    }


    private static QueryFieldMetadata getQueryFieldMetadataFromResultSet(ResultSet rs)throws SQLException{
        QueryFieldMetadata md = new QueryFieldMetadata();
        md.setFieldId(rs.getString("query_field_id"));
        md.setQueryId(rs.getString("query_md_id"));
        md.setTableAliasName(rs.getString("table_alias_name"));
        md.setFieldName(rs.getString("field_name"));
        md.setUsedFieldNameAsKey(rs.getBoolean("used_field_name_as_key"));
        md.setDisplayName(rs.getString("display_name"));
        md.setDisplayNameTag(rs.getString("display_name_tag"));
        md.setDataType(DataType.valueOf(rs.getString("data_type")));
        md.setPrimaryKey(rs.getBoolean("is_pk"));
        md.setWidth(rs.getInt("width"));
        if(rs.wasNull()){
            md.setWidth(null);
        }
        md.setSortSupported(rs.getBoolean("sort_supported"));
        md.setColumnDataAlign(DataAlign.valueOf(rs.getString("column_data_align")));
        md.setColumnHeaderAlign(DataAlign.valueOf(rs.getString("column_header_align")));
        md.setDisplayOrder(rs.getInt("display_order"));

        md.setClientFormatter(rs.getString("client_formatter"));
        md.setFormatterMethodName(rs.getString("formatter_method_name"));
        md.setFooterCalcSupported(rs.getBoolean("footer_calc_supported"));
        md.setSuppressible(rs.getBoolean("suppressible"));
        md.setDefaultSort(rs.getBoolean("as_default_sort"));
        md.setDefaultSortOrder(rs.getString("default_sort_order"));
        md.setAsTreeField(rs.getBoolean("as_tree_field"));
        md.setAsTreeParentField(rs.getBoolean("as_tree_parent_field"));
        md.setDictionaryId(rs.getString("format_type"));
        if(StringUtils.isNotEmpty(md.getDictionaryId())){
            md.setFormatType(FormatType.valueOf(rs.getString("format_type")));
            md.setFormatOptions(rs.getString("format_options"));
        }else{
            md.setFormatType(FormatType.NONE);
        }
        md.setDictionaryId(rs.getString("dictionary_id"));
        return md;
    }
}
